"""
场景实体
单位约定如下：
距离单位 百米
速度单位 百米/秒
"""

import math,os,sys,time,json,random
import matplotlib.pyplot as plt
import numpy as np
from Entities.SAM import SAM
from Entities.UCAV import UCAV

para=json.load(open('Config/SceneConfig.json','r',encoding='UTF-8'))

class Scenes():
    def __init__(self, N_R, N_B,Process_index=0,Init_random=True,Decision=None):
        self.dt = para['dt']        # 每回合间隔时间
        self.Init_Range = para['Init_range']    # 初始无人机群位置
        self.Exit_Range=para['Exit_range']  # 退出位置
        self.N_R=N_R
        self.N_B=N_B
        self.Store_Location_R = []  # 红方坐标列表，记录以往的所有坐标,结构为三层数组，第一层为回合，第二层为单位，第三层为坐标
        self.Store_Location_B = []  # 蓝方坐标列表，记录以往的所有坐标,结构同上
        self.Store_Location_MR=[]
        self.Store_Location_MB=[]
        self.PI=Process_index       # 线程实例序号
        self.Red=[UCAV('UCAV'+str(i),0) for i in range(N_R)]
        self.Blue=[SAM('SAM'+str(i),1) for i in range(N_B)]
        self.Missile_in_Sce=[]  # 激活的导弹
        self.Missile_out_Sce=[] # 失效的导弹
        if Init_random==True:
            self._Init_random()
        else:
            self._Entities_init(Decision)

    def _Init_random(self):
        Random_target=np.random.randint(0,self.N_B,self.N_R)
        Random_position=np.random.randint(0,para['Theta_separate']*para['Phi_separate'],self.N_R)
        decision=np.column_stack([Random_target,Random_position])   # 按列组合形成随机决策组
        self._Entities_init(decision)

    def _Entities_init(self,decision):
        B_Range=para['Init_range_Blue']
        for B in self.Blue:     # 蓝方围绕坐标原点生成
            ran = np.random.uniform(-B_Range, B_Range, 3)     # 蓝方出生随机范围-5~5
            ran[2] = 0.
            B.Position = ran

        def Points_in_Ball(r):
            points = []
            for i in range(1, para['Theta_separate']+1):  # 如，theta=6，取值 15,30,45,60,75
                for j in range(para['Phi_separate']):  # phi=12，取值0-360，步长30
                    Theta = (math.pi/2) / para['Theta_separate']*2 * i  # 对90进行等分
                    Phi = (math.pi*2) / para['Phi_separate'] * j    # 对360进行等分
                    x = r * math.sin(Theta) * math.cos(Phi)
                    y = r * math.sin(Theta) * math.sin(Phi)
                    z = r * math.cos(Theta)
                    points.append([x, y, z])
            return points
        Points_Start = Points_in_Ball(self.Init_Range)  # 球面坐标集合，半径Init_Range
        for R in range(len(self.Red)):
            pn = Points_Start[decision[R][1]]  # 球面穷举的位置坐标，也为敌方的射程能够达到的（x,y,z）距离
            pe = self.Blue[decision[R][0]].Position  # 敌方位置
            pf = pn + pe
            self.Red[R].Position = pf
            self.Red[R].Pointing = [math.pi / 2, math.atan2(-pn[1], -pn[0])]  # [俯仰角，偏转角]，要取反方向要在xy上加负号

        self.Record_Location_in_Memory()

    def Record_Location_in_Memory(self):
        Location_R = [R.Position for R in self.Red]
        Location_B = [B.Position for B in self.Blue]
        Location_MR=[M.Position for M in self.Missile_in_Sce if M.Lable==0]
        Location_MB=[M.Position for M in self.Missile_in_Sce if M.Lable==1]
        self.Store_Location_R.append(Location_R.copy())
        self.Store_Location_B.append(Location_B.copy())
        self.Store_Location_MR.append(Location_MR.copy())
        self.Store_Location_MB.append(Location_MB.copy())


    def Observate(self):
        pass
